package cn.bigfire.wedesk.store;

import cn.bigfire.wedesk.bean.Wedesk;
import cn.bigfire.wedesk.net.protocol.Protocol;
import cn.bigfire.wedesk.service.bo.CustInfo;
import cn.bigfire.wedesk.service.bo.UserEntity;
import io.netty.channel.Channel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class Stores {


    //由于没有service层和dao层，先临时放内存,理论上应该放在数据库

    //用户相关
    private static final ConcurrentHashMap<String, UserEntity> registerUsers = new ConcurrentHashMap<>();//<用户名,用户对象>

    public static boolean hasUserName(String username){
        return registerUsers.containsKey(username);
    }

    public static void register(UserEntity userEntity){
        registerUsers.put(userEntity.getUsername(), userEntity);
    }

    public static UserEntity findUserByUsername(String username){
        return registerUsers.get(username);
    }


    //设备相关
    private static final Map<String, Wedesk.PCInfo> pcInfoMap = new ConcurrentHashMap<>();//<设备uid,设备信息>
    private static final Map<String, Map<String, Wedesk.PCInfo>> custPcInfoMap = new ConcurrentHashMap<>();//<用户名,<设备uid,设备信息>>

    public static List<Wedesk.PCInfo> findAllPcInfos() {
        return new ArrayList<>(pcInfoMap.values());
    }

    public static void addPcInfo(String channelId, Wedesk.PCInfo pcInfo) {
        pcInfoMap.put(channelId, pcInfo);
    }

    public static void bindCustPcInfo(String channelId,String username) {
        if (channelId != null && username != null && pcInfoMap.containsKey(channelId)) {
            Wedesk.PCInfo pcInfo = pcInfoMap.get(channelId);
            if (pcInfo != null) {
                Map<String, Wedesk.PCInfo> myOnlineDeviceMap = findPcInfosByUsername(username);
                myOnlineDeviceMap.putIfAbsent(channelId, pcInfo);//把其他设备存起来之后，再把自己放进去
                Stores.custPcInfoMap.putIfAbsent(username, myOnlineDeviceMap);//成功登录
            }
        }
    }

    public static void removePcInfo(String channelId) {
        pcInfoMap.remove(channelId);
        //用户关联设备信息删除
        Set<String> usernames = custPcInfoMap.keySet();
        for (String username : usernames) {
            Map<String, Wedesk.PCInfo> userMap = custPcInfoMap.getOrDefault(username, new HashMap<>());
            userMap.remove(channelId);
            custPcInfoMap.put(username, userMap);
        }
    }



    public static Map<String, Wedesk.PCInfo> findPcInfosByUsername(String username) {
        return custPcInfoMap.getOrDefault(username, new ConcurrentHashMap<>());
    }

    //控制相关
    private static final ConcurrentHashMap<String, ConcurrentHashMap<String, Wedesk.Ctrl>> ctrlMap = new ConcurrentHashMap<>();//<被控用户cid,<fromId,控制镀锡>>
    public static final ConcurrentHashMap<String, HashSet<String>> ctrlSet = new ConcurrentHashMap<>();//<被控用户cid,<控制用户列表>>
    public static final ConcurrentHashMap<String, CustInfo> custOnline = new ConcurrentHashMap<>();//<用户cid,用户对象>

    public static void closeMyCtrl(String fromId) {
        ctrlMap.forEach((cid,map)->{
            if (map.containsKey(fromId)) {
                Channel channel = Threads.getChannel(cid);
                Wedesk.Ctrl ctrlExecReq = new Wedesk.Ctrl();
                ctrlExecReq.setFromCid(fromId);
                ctrlExecReq.setToCid(cid);
                channel.writeAndFlush(Protocol.of(Wedesk.Cmd.CMD_CTRL_CLOSE, ctrlExecReq));
            }
        });
    }

    public static ConcurrentHashMap<String, Wedesk.Ctrl> findCtrlMap(String toCid) {
        return ctrlMap.getOrDefault(toCid, new ConcurrentHashMap<>());
    }

    public static void addCtrlOpen(Wedesk.Ctrl ctrl) {
        String toCid = ctrl.getToCid();
        String fromCid = ctrl.getFromCid();
        ConcurrentHashMap<String, Wedesk.Ctrl> map = ctrlMap.getOrDefault(toCid, new ConcurrentHashMap<>());
        map.put(fromCid, ctrl);
        ctrlMap.put(toCid, map);
    }

    public static void removeCtrlOpen(Wedesk.Ctrl ctrlExecReq) {
        String toCid = ctrlExecReq.getToCid();
        String fromCid = ctrlExecReq.getFromCid();
        ConcurrentHashMap<String, Wedesk.Ctrl> map = ctrlMap.get(toCid);
        if (map != null) {
            map.remove(fromCid);
        }
    }


}
